﻿using LibBinary.DataSource;
using LibBinary.FileData;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LibBinary.FileDeclaration.Binary
{
    public interface ILengthProvider
    {
        int GetLength(AbstractFileData data);
    }

    public class ConstLengthProvider : ILengthProvider
    {
        private readonly int length;

        public ConstLengthProvider(int length)
        {
            this.length = length;
        }

        public int GetLength(AbstractFileData data)
        {
            return length;
        }
    }

    public class ReferenceLengthProvider : ILengthProvider
    {
        private readonly int index;

        public ReferenceLengthProvider(int index)
        {
            this.index = index;
        }

        public int GetLength(AbstractFileData data)
        {
            var parent = data.Parent.As<StructuredData>();

            if (parent == null || index < 0 || index >= parent.Data.Length)
            {
                throw new ReadingFormatException("Can not access length field.");
            }
            var pri = parent.Data[index].As<SystemPrimitiveData>();
            if (pri == null || !pri.IntData.HasValue)
            {
                throw new ReadingFormatException("Length field does not contain an integer.");
            }
            return pri.IntData.Value;
        }
    }
}
